﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Web;

namespace VisaValeCheck
{
    /// <summary>
    /// Interaction logic for Window1.xaml
    /// </summary>
    public partial class Window1 : Window
    {
        private System.Windows.Forms.NotifyIcon _icone = new System.Windows.Forms.NotifyIcon();
        private Visa _visa = null;
        private NumeroCartao _numeroSelecionado;
                
        public Window1()
        {
            Apoio.Dispatcher = Dispatcher;
            InitializeComponent();
            this.MontaTrayMenus();
            _visa = new Visa();
            _visa.TudoBeleza += new EventHandler(_visa_TudoBeleza);
            _visa.Carregando += new EventHandler(_visa_Carregando);
            _visa.ErroAoAtualizar += new EventHandler(_visa_ErroAoAtualizar);
            _visa.NovoDeposito += new EventHandler(_visa_NovoDeposito);
            _visa.NovaCompra += new EventHandler(_visa_NovaCompra);
            _visa.DataDoCreditoDefinida += new EventHandler(_visa_ValoresAtualizados);
            if (_visa.Saldo != null)
                _numeroSelecionado = _visa.Saldo.NumeroCartao;            
            this.TrocaIcone(new Uri("Imagens/Icone.ico", UriKind.Relative));            
            PluginHelper.EventoNoPlugin += new VisaValeCheckPluginBase.EventoNoPluginDelegate(PluginHelper_EventoNoPlugin);
            PluginHelper.CarregarPlugins(_visa);            
        }

        private IDictionary<string, string> _strPluginsDic = new Dictionary<string, string>();
        void PluginHelper_EventoNoPlugin(VisaValeCheckPluginBase plugin, string mensagem)
        {
            string msg = string.Format("*[{0}]: {1}", plugin.Nome, mensagem);
            if (!_strPluginsDic.Keys.Contains(plugin.Nome))
            {
                _strPluginsDic.Add(plugin.Nome, msg);
            }
            else
            {
                _strPluginsDic[plugin.Nome] = msg;
            }            
            VisaDisplayInfoWPF info = (VisaDisplayInfoWPF)Resources["info"];
            if (!info.Plugins.Any((a) =>
            {
                return a.Plugin == plugin;
            }))
            {
                info.Plugins.Add(new VisaDisplayInfoPluginWPF() { Plugin = plugin, Mensagem = mensagem });
            }
            else
            {
                VisaDisplayInfoPluginWPF pluginAtualizado = info.Plugins.First((a) => a.Plugin == plugin);
                pluginAtualizado.Mensagem = mensagem;
            }
        }

        void _visa_ValoresAtualizados(object sender, EventArgs e)
        {
            _icone.BalloonTipTitle = "Data do próximo crédito definida!";
            _icone.BalloonTipText = "Comemore! Foi definida a data do próximo crédito.\nUm churrasco para comemorar?";
            _icone.ShowBalloonTip(60000);
        }

        private void TrocaIcone(Uri imagem)
        {
            using (System.IO.Stream stIcone = App.GetResourceStream(imagem).Stream)
            {
                _icone.Icon = new System.Drawing.Icon(stIcone);
            }
        }

        void _visa_Carregando(object sender, EventArgs e)
        {
            this.TrocaIcone(new Uri("Imagens/Loading.ico", UriKind.Relative));            
            this.MontaTrayInfo("Carregando informações...", true);                        
        }

        private delegate void X();
        void _visa_TudoBeleza(object sender, EventArgs e)
        {
            this.TrocaIcone(new Uri("Imagens/Icone.ico", UriKind.Relative));
            StringBuilder strBalloon = new StringBuilder();
            strBalloon.AppendLine(string.Format("Cartão número: {0}", _visa.Saldo.NumeroCartao.NumeroFormatado));
            strBalloon.AppendLine(string.Format("Data do benefício: {0:dd/MM/yyyy}", _visa.Saldo.UltimoDeposito));
            strBalloon.AppendLine(string.Format("Saldo disponível: {0:0.00}", _visa.Saldo.SaldoDisponivel));
            if (_visa.Saldo.UltimaCompra != null)
            {
                strBalloon.AppendLine(string.Format("Última compra: {0:dd/MM} {1} (R$ {2:0.00})", _visa.Saldo.UltimaCompra.Data, _visa.Saldo.UltimaCompra.Local, _visa.Saldo.UltimaCompra.Valor));
            }
            if (_visa.Saldo.ProximoDeposito != null)
            {
                strBalloon.AppendLine(string.Format("Próximo benefício: R$ {0:0.00} em {1:dd/MM/yyyy}", _visa.Saldo.ProximoDeposito.Valor, _visa.Saldo.ProximoDeposito.Data));
            }            
            //Processar os plugins
            PluginHelper.RodarPlugins(_visa.Saldo);
            strBalloon.AppendLine("----------");
            foreach (KeyValuePair<string, string> x in _strPluginsDic)
            {
                strBalloon.AppendLine(x.Value);
            }
            this.AtualizaInfo(_visa.Saldo);
            this.MontaTrayInfo(strBalloon.ToString().Trim(), true);
        }

        void _visa_NovaCompra(object sender, EventArgs e)
        {
            _icone.BalloonTipTitle = "Nova compra!";
            _icone.BalloonTipText = "Foi efetuada uma nova compra com seu cartão!";
            _icone.ShowBalloonTip(60000);
        }

        void _visa_NovoDeposito(object sender, EventArgs e)
        {
            _icone.BalloonTipTitle = "Novo deposíto!";
            _icone.BalloonTipText = string.Format("Foi efetuado um novo depósito (R$ {0:0.00} disponíveis(el))", _visa.Saldo.SaldoDisponivel);
            _icone.ShowBalloonTip(10000);
        }

        void _visa_ErroAoAtualizar(object sender, EventArgs e)
        {
            this.MontaTrayErro("Por favor, verifique se você está conectado a internet ou se digitou corretamente o número do cartão.");
        }

        private delegate void DelAux();
        private DelAux _x = null;

        private void TrayClick(object sender, System.Windows.Forms.MouseEventArgs e)
        {
            if (e.Button == System.Windows.Forms.MouseButtons.Left)
            {
                if (_x != null)
                    _x();
                WMain.Visibility = (WMain.Visibility == System.Windows.Visibility.Visible ? System.Windows.Visibility.Hidden : System.Windows.Visibility.Visible);
            }
        }

        private void MontaTrayErro(string mensagem)
        {
            _x = delegate()
            {
                _icone.BalloonTipIcon = System.Windows.Forms.ToolTipIcon.Error;
                _icone.BalloonTipTitle = "Erro";
                _icone.BalloonTipText = string.Format(mensagem);
                _icone.ShowBalloonTip(3000);
            };
            _x();            
        }

        private void MontaTrayInfo(string mensagem, bool mostrar)
        {
            _x = delegate()
            {
                _icone.BalloonTipIcon = System.Windows.Forms.ToolTipIcon.Info;
                _icone.BalloonTipTitle = "Informações";
                _icone.BalloonTipText = mensagem;
                _icone.ShowBalloonTip(5000);
                this.Visibility = (mostrar ? Visibility.Visible : Visibility.Hidden);
            };
            if (mostrar)
                _x();
        }

        private void AtualizaInfo(VisaSaldo saldo)
        {
            VisaDisplayInfoWPF info = (VisaDisplayInfoWPF)Resources["info"];
            info.NumeroCartao = saldo.NumeroCartao.NumeroFormatado;
            info.SaldoDisponivel = saldo.SaldoDisponivel;
            info.UltimaCompra = saldo.UltimaCompra;
            info.UltimoBeneficio = saldo.UltimoBeneficio;
            info.ProximoDeposito = saldo.ProximoDeposito;
        }

        private void MontaTrayMenus()
        {
            _icone.Visible = true;
            _icone.MouseClick += TrayClick;
            System.Windows.Forms.ContextMenuStrip menu = new System.Windows.Forms.ContextMenuStrip();
            System.Windows.Forms.ToolStripMenuItem menuI = new System.Windows.Forms.ToolStripMenuItem();
            menuI.Text = "Cartões";
            menuI.MouseDown += delegate(object sender, System.Windows.Forms.MouseEventArgs e)
            {
                if (e.Button == System.Windows.Forms.MouseButtons.Left)
                {
                    NumeroWindow wNW = new NumeroWindow();
                    if (_visa.Saldo != null)
                    {
                        try
                        {
                            wNW.NumeroCartao = _visa.Saldo.NumeroCartao;
                        }
                        catch (Exception)
                        {
                            wNW.NumeroCartao = null;
                        }
                    }
                    if ((bool)wNW.ShowDialog())
                    {
                        _numeroSelecionado = wNW.NumeroCartao;
                        _numeroSelecionado.Selecionado = true;
                        _visa.Consulta(_numeroSelecionado);
                    }
                }                
            };
            menu.Items.Add(menuI);

            menuI = new System.Windows.Forms.ToolStripMenuItem();
            menuI.Text = "Atualizar";
            menuI.Click += delegate(object sender, EventArgs e) { _visa.Consulta(_numeroSelecionado); };
            menu.Items.Add(menuI);

            menuI = new System.Windows.Forms.ToolStripMenuItem();
            menuI.Text = "Relatório";
            menuI.Click += delegate(object sender, EventArgs e)
            {
                RelatorioWindow rel = new RelatorioWindow();
                rel.ShowDialog();
            };
            menu.Items.Add(menuI);

            menuI = new System.Windows.Forms.ToolStripMenuItem();
            menuI.Text = "Sair";
            menuI.Click += delegate(object sender, EventArgs e)
            {
                _icone.Dispose();
                _visa.Sair();
                this.Close();
            };
            menu.Items.Add(menuI);
            _icone.ContextMenuStrip = menu;
        }      

        private void ComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            if (e.AddedItems.Count > 0)
            {
                NumeroCartao cartao = e.AddedItems[0] as NumeroCartao;
                VisaSaldo saldo = SaldosSerialization.Saldos.First((a) => a.NumeroCartao == cartao);
                this.AtualizaInfo(saldo);
            }
        }

        private void WMain_Closing(object sender, System.ComponentModel.CancelEventArgs e)
        {
            if (_visa != null)
            {
                _icone.Dispose();
                _visa.Sair();
            }
        }

        private void btnRefresh_Click(object sender, RoutedEventArgs e)
        {
            if (cmbCartao.SelectedItem != null)
                _visa.Consulta((NumeroCartao)cmbCartao.SelectedItem);
        }       
    }
}
